/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.alphawavesgames.engine.rendering;

import com.alphawavesgames.engine.game.EngineInitListener;


/**
 *
 * @author duncan
 */
public abstract class RenderContainer
{
    //the singleton
    protected static RenderContainer s_renderContainer = null;

    //a notification object that needs to be told when the engine is initialised
    //( for now the engine is just the RenderContainer )
    protected EngineInitListener m_onInitCallback;

    //all the rendering engine classes we need for rendering
    //the render hardware interface
    protected RenderHWInterface m_renderInterface;
    protected SpriteRenderer    m_spriteRenderer;
    protected TextureManager    m_textureManager;
    protected FontRenderer      m_fontRenderer;
    //protected ShapeRenderer     m_shapeRenderer;

    protected RenderContainer()
    {
        m_onInitCallback = null;
        m_renderInterface = null;

        //it's up to the derived implementation to create these for a specific platform
        m_spriteRenderer = null;
        m_textureManager = null;
        m_fontRenderer = null;
        //m_shapeRenderer = null;
    }

    //get the singleton
    public static RenderContainer getRenderContainer()
    {
        return s_renderContainer;
    }

    //create the singleton
    /*public static RenderContainer createRenderContainer()
    {
        if( s_renderContainer == null )
        {
            s_renderContainer = new RenderContainer();
        }
        return s_renderContainer;
    }*/

    public void registerOnInitListener( EngineInitListener listener )
    {
        //only supports one listener for now
        assert( m_onInitCallback == null );
        m_onInitCallback = listener;
    }

    public void onRenderHWInterfaceCreated()
    {

    }

    //have to override this to make sure initialisation occurs with the correct
    //RenderContainer derived class.
    public abstract void initialise();

    public void finalise()
    {
        if( m_spriteRenderer != null )
        {
            m_spriteRenderer.finalise();
        }

        if( m_textureManager != null )
        {
            m_textureManager.finalise();
        }
    }

    public void update()
    {
        //process updates of all the systems
        m_textureManager.update();
    }

    public void render()
    {
        m_spriteRenderer.render();
    }

    public void beginScene()
    {
        //begin the scene/frame
        //waits for render thread to finish first
        //since the rendering is not working on separate data yet we
        //can't allow the update to work in parallel with the rendering.
        m_renderInterface.beginScene();

        //let all components know a new scene is beginning
        m_spriteRenderer.beginScene();
    }

    public void endScene()
    {
        m_spriteRenderer.endScene();
        
        //finally end the scene for the render interface to let
        //it know it can start work on rendering the frame
        m_renderInterface.endScene();
    }


    public RenderHWInterface getRenderHWInterface() { return m_renderInterface; }
    //access to all the engine classes
    public SpriteRenderer getSpriteRenderer() { return m_spriteRenderer; }
    public TextureManager getTextureManager() { return m_textureManager; }
    public FontRenderer getFontRenderer() { return m_fontRenderer; }
    //public ShapeRenderer getShapeRenderer() { return m_shapeRenderer; }

}
